package com.macro.mall.tiny.modules.pms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.macro.mall.tiny.dto.PmsProductConditionDTO;
import com.macro.mall.tiny.dto.ProductSaveParamsDTO;
import com.macro.mall.tiny.modules.pms.model.PmsProduct;
import com.macro.mall.tiny.modules.pms.mapper.PmsProductMapper;
import com.macro.mall.tiny.modules.pms.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 * 商品信息 服务实现类
 * </p>
 *
 * @author macro
 * @since 2024-08-15
 */
@Service
public class PmsProductServiceImpl extends ServiceImpl<PmsProductMapper, PmsProduct> implements PmsProductService {

    @Autowired
    private PmsMemberPriceService memberPriceService;

    @Autowired
    private PmsProductLadderService productLadderService;

    @Autowired
    private PmsProductFullReductionService productFullReductionService;

    @Autowired
    private PmsSkuStockService skuStockService;

    @Autowired
    private PmsProductAttributeValueService productAttributeValueService;

    @Autowired
    private PmsProductMapper productMapper;

    @Override
    public Page<PmsProduct> list(PmsProductConditionDTO pmsProductConditionDTO) {
        Page<PmsProduct> page = new Page<>(pmsProductConditionDTO.getPageNum(), pmsProductConditionDTO.getPageSize());
        QueryWrapper<PmsProduct> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(pmsProductConditionDTO.getKeyword() != null, PmsProduct::getName, pmsProductConditionDTO.getKeyword())
                .eq(pmsProductConditionDTO.getPublishStatus() != null, PmsProduct::getPublishStatus, pmsProductConditionDTO.getPublishStatus())
                .eq(pmsProductConditionDTO.getVerifyStatus() != null, PmsProduct::getVerifyStatus, pmsProductConditionDTO.getVerifyStatus())
                .like(pmsProductConditionDTO.getProductSn() != null, PmsProduct::getProductSn, pmsProductConditionDTO.getProductSn())
                .eq(pmsProductConditionDTO.getBrandId() != null, PmsProduct::getBrandId, pmsProductConditionDTO.getBrandId())
                .eq(pmsProductConditionDTO.getProductCategoryId() != null, PmsProduct::getProductCategoryId, pmsProductConditionDTO.getProductCategoryId())
                .orderByDesc(PmsProduct::getSort);
        return page(page, queryWrapper);
    }

    @Override
    public boolean updateStatus(List<Long> ids, Integer status, SFunction<PmsProduct, ?> setter) {
        UpdateWrapper<PmsProduct> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().in(PmsProduct::getId, ids).set(setter, status);
        return update(updateWrapper);
    }

    @Override
    @Transactional
    public boolean create(ProductSaveParamsDTO productSaveParamsDTO) {
        boolean result = save(productSaveParamsDTO);
        if (result) {
            switch (productSaveParamsDTO.getPromotionType()) {
                case 2:
                    saveManyList(productSaveParamsDTO.getMemberPriceList(), productSaveParamsDTO.getId(), memberPriceService);
                    break;
                case 3:
                    saveManyList(productSaveParamsDTO.getProductLadderList(), productSaveParamsDTO.getId(), productLadderService);
                    break;
                case 4:
                    saveManyList(productSaveParamsDTO.getProductFullReductionList(), productSaveParamsDTO.getId(), productFullReductionService);
                    break;
            }
            saveManyList(productSaveParamsDTO.getSkuStockList(), productSaveParamsDTO.getId(), skuStockService);
            saveManyList(productSaveParamsDTO.getProductAttributeValueList(), productSaveParamsDTO.getId(), productAttributeValueService);
        }
        return true;
    }

    @Override
    public ProductSaveParamsDTO getProduct(Long id) {
        return productMapper.getProduct(id);
    }

    @Override
    @Transactional
    public boolean update(ProductSaveParamsDTO productSaveParamsDTO) {
        boolean result = updateById(productSaveParamsDTO);
        if (result) {
            switch (productSaveParamsDTO.getPromotionType()) {
                case 2:
                    deleteManyList(productSaveParamsDTO.getId(), memberPriceService);
                    saveManyList(productSaveParamsDTO.getMemberPriceList(), productSaveParamsDTO.getId(), memberPriceService);
                    break;
                case 3:
                    deleteManyList(productSaveParamsDTO.getId(), productLadderService);
                    saveManyList(productSaveParamsDTO.getProductLadderList(), productSaveParamsDTO.getId(), productLadderService);
                    break;
                case 4:
                    deleteManyList(productSaveParamsDTO.getId(), productFullReductionService);
                    saveManyList(productSaveParamsDTO.getProductFullReductionList(), productSaveParamsDTO.getId(), productFullReductionService);
                    break;
            }
            deleteManyList(productSaveParamsDTO.getId(), skuStockService);
            saveManyList(productSaveParamsDTO.getSkuStockList(), productSaveParamsDTO.getId(), skuStockService);
            deleteManyList(productSaveParamsDTO.getId(), productAttributeValueService);
            saveManyList(productSaveParamsDTO.getProductAttributeValueList(), productSaveParamsDTO.getId(), productAttributeValueService);
        }
        return true;
    }

    private void deleteManyList(Long id, IService service) {
        QueryWrapper<Object> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_id", id);
        service.remove(queryWrapper);
    }

    public void saveManyList(List list, Long productId, IService service) {
        if (CollectionUtil.isEmpty(list)) return;
        try {
            // 循环反射，设置productId
            for (Object obj : list) {
                Method setProductIdMethod = obj.getClass().getMethod("setProductId", Long.class);
                // 修改状态清除id为null
                Method setId = obj.getClass().getMethod("setId", Long.class);
                setId.invoke(obj, (Long) null);
                // 设置productId
                setProductIdMethod.invoke(obj, productId);
            }
            service.saveBatch(list);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}